package com.dev.security.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.dev.security.entity.Role;
import com.dev.security.entity.User;
import com.dev.security.entity.UserRole;
import com.dev.security.mapper.RoleMapper;
import com.dev.security.mapper.UserMapper;
import com.dev.security.mapper.UserRoleMapper;
import com.dev.security.service.UserService;
import com.dev.security.util.PasswordHash;
import com.dev.security.vo.PageVo;
import com.dev.security.vo.RoleVo;
import com.dev.security.vo.UserVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 此处为类介绍
 *
 * @author yuboon
 * @version v1.0
 * @date 2020/04/04
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    @Transactional
    public int save(UserVo userVo) {
        User userEntity = new User();
        // hutool
        BeanUtil.copyProperties(userVo, userEntity);
        userEntity.setCreateDate(new Date());
        userEntity.setPassword(PasswordHash.createHash(userEntity.getPassword()));
        return userMapper.insert(userEntity);
    }

    @Override
    @Transactional
    public int update(UserVo userVo) {
        User userEntity = new User();

        BeanUtil.copyProperties(userVo, userEntity);
        if (StrUtil.isNotEmpty(userVo.getPassword())) {
            userEntity.setPassword(PasswordHash.createHash(userEntity.getPassword()));
        }
        return userMapper.update(userEntity);
    }

    @Override
    @Transactional
    public int remove(int id) {
        return userMapper.remove(id);
    }

    @Override
    public int batchRemove(String ids) {
        JSONArray jsonArray = JSONUtil.parseArray(ids);
        for (Object id : jsonArray) {
            userMapper.remove(Convert.toInt(id));
        }
        return jsonArray.size();
    }

    @Override
    public PageVo<UserVo> selectList(UserVo userVo, PageVo pageVo) {
        if (StrUtil.isNotEmpty(userVo.getPhone())) {
            userVo.setPhone("%" + userVo.getPhone() + "%");
        }
        List<UserVo> listVo = CollectionUtil.newArrayList();
        Page page = PageHelper.startPage(pageVo.getPage(), pageVo.getLimit());

        User user = new User();
        BeanUtil.copyProperties(userVo, user);
        List<User> listEntity = userMapper.selectList(user);
        for (User entity : listEntity) {
            UserVo vo = new UserVo();
            BeanUtil.copyProperties(entity, vo);
            vo.setCreateDate(DateUtil.formatDate(entity.getCreateDate()));
            listVo.add(vo);
        }
        pageVo.setList(listVo);
        pageVo.setTotal(page.getTotal());

        return pageVo;
    }

    @Override
    @Transactional
    public int assignRole(int userId, String roleIds) {
        JSONArray jsonArray = JSONUtil.parseArray(roleIds);
        //先删除
        userRoleMapper.deleteByUserId(userId);
        //后保存
        for (Object roleId : jsonArray) {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(Convert.toInt(roleId));
            int count = userRoleMapper.selectByUserRole(userRole);
            if (count > 0) {
                continue;
            }

            userRoleMapper.insert(userRole);
        }
        return 0;
    }

    @Override
    public List<RoleVo> selectAssignRole(int userId) {
        List<Role> allRoles = roleMapper.selectList(new Role());
        List<Role> assignRoles = userMapper.selectAssignRole(userId);
        ArrayList<RoleVo> roleVoList = CollectionUtil.newArrayList();
        for (Role role : allRoles) {
            RoleVo roleVo = new RoleVo();
            BeanUtil.copyProperties(role,roleVo);

            roleVo.setLAY_CHECKED(has(role.getId(),assignRoles));
            roleVoList.add(roleVo);
        }
        return roleVoList;
    }

    private boolean has(int roleId,List<Role> assignRoles){
        for (Role role : assignRoles) {
            if (roleId == role.getId()){
                return true;
            }
        }
        return false;
    }

    @Override
    public String selectPasswordByUsername(Object username) {
        return userMapper.selectPasswordByUsername(username);
    }

    @Override
    public UserVo selectByUsername(String username) {
        User user = userMapper.selectByUsername(username);
        UserVo userVo = new UserVo();
        BeanUtil.copyProperties(user,userVo);
        return userVo;
    }

    @Override
    public int updatePass(String oldPass, String newPass) {
        Object username = SecurityUtils.getSubject().getPrincipal();
        String encodePassword = userMapper.selectPasswordByUsername(username);
        boolean isMatch = PasswordHash.validatePassword(oldPass, encodePassword);
        if (isMatch){
            UserVo userVo = (UserVo) SecurityUtils.getSubject().getSession().getAttribute("loginUser");
            return userMapper.updatePass(userVo.getId(),PasswordHash.createHash(newPass));
        }
        return 0;
    }
}
